<?php

namespace App\Http\Controllers;

use App\Enums\OrderEnum;
use App\Http\Logic\MachineLogic;
use App\Http\Logic\OrderLogic;
use App\Http\Requests\OrderRequest;
use App\Jobs\CancelOrder;
use Illuminate\Support\Facades\Cache;

class OrderController extends BaseController
{
    /**
     * @notes 创建订单
     * @param OrderRequest $request
     * @return \Dingo\Api\Http\Response
     * @author Evil丿
     * @date 2024/05/06 10:52
     */
    public function createOrder(OrderRequest $request)
    {
        $params = $request -> post();

        try {
            //获取原子锁控制并发操作
            $lock = Cache::lock('lock_machine_'.$params['machineCode'].'_'.$params['doorNum']);
            if (!$lock -> get()) {
                throw new \Exception('设备已被占用');
            }

            //判断设备当前是否可以下单
            $machine_info = MachineLogic::checkMachineSaleStatus($params['machineCode'], $params['doorNum'], $this -> user_info -> id);
            if($machine_info === false) {
                throw new \Exception(MachineLogic::getErrorMessage());
            }

            //判断用户当前是否可下单
            $res = OrderLogic::getUserOrderStatus($this -> user_info -> id, $params['platform']);
            if($res === false) {
                throw new \Exception(OrderLogic::getErrorMessage());
            }

            //创建支付分订单
            $order_info = OrderLogic::createPayOrder($params['platform'], $this -> user_info -> id, $machine_info['id'], $params['doorNum']);
            if($order_info === false) {
                throw new \Exception(OrderLogic::getErrorMessage());
            }

            //设置预授权时间
            $auth_time = 3;

            //设备已被占用状态，设备状态存入redis,设置3分钟失效（延迟10秒，保证在订单取消后才会解锁）。
            MachineLogic::setMachineCacheLock($machine_info['source_type'], $params['machineCode'], $params['doorNum'], $order_info, 60 * $auth_time + 10);

            //定时任务，3分钟未授权自动取消订单
            CancelOrder::dispatch($order_info['id'], $auth_time, OrderEnum::ORDER_CREATED) -> onQueue('order_state');

            $res = $this->success($order_info['auth_params']);

        } catch (\Exception $e) {

            $res = $this->error($e->getMessage());

        } finally {
            if($lock) {
                //无论结果如何释放设备锁
                optional($lock)->release();
            }
        }

        return $res;
    }

    /**
     * @notes 查询支付分授权状态
     * @param OrderRequest $request
     * @return \Dingo\Api\Http\Response
     * @author Evil丿
     * @date 2024/05/06 10:54
     */
    public function getOrderStatus(OrderRequest $request)
    {
        $params = $request -> post();

        //获取订单信息
        $order_info = OrderLogic::getOrderWithUserInfo($params['orderId']);

        if($order_info === false) {
            return $this->error(OrderLogic::getErrorMessage());
        }

        try {
            //未通过授权
            if(!$params['confirm']) {
                throw new \Exception('用户未通过授权');
            }

            //查询订单实际状态
            $state = OrderLogic::getOrderAuthStatus($order_info['order_sn'], $order_info['platform'], $params['confirm']);
            if($state === false) {
                throw new \Exception(OrderLogic::getErrorMessage());
            }

            //订单状态非进行中抛出当前实际状态
            if($state !== OrderEnum::ORDER_DOING) {
                throw new \Exception(OrderEnum::getOrderStateDesc($state));
            }

            //通知设备开门
            $res = MachineLogic::openDoor($order_info);
            if($res === false) {
                throw new \Exception(MachineLogic::getErrorMessage());
            }

            //设备已被占用状态，设备状态存入redis,设置30分钟失效（延迟10秒，保证在订单取消后才会解锁）。
            MachineLogic::setMachineCacheLock($order_info['machine']['source_type'], $order_info['machine']['machine_no'], $order_info['door_num'], $order_info,60 * 30 + 10);
            //进行中订单设置30分钟回调时间，时间内未回调自动取消
            CancelOrder::dispatch($params['orderId'], 30, OrderEnum::ORDER_DOING)->onQueue('order_state');

            return $this->success(['order_id' => $params['orderId']],"门锁已打开");

        } catch (\Exception $e) {
            OrderLogic::cancelOrder($order_info['order_sn'], $order_info['door_num'], $order_info['platform']);
            return $this->error($e -> getMessage());
        }
    }

    /**
     * @notes 获取订单完成状态
     * @param OrderRequest $request
     * @return \Dingo\Api\Http\Response
     * @author Evil丿
     * @date 2024/05/06 14:57
     */
    public function getOrderFinish(OrderRequest $request)
    {
        $order_id = $request -> get('orderId');

        $order_info = OrderLogic::getOrderInfo($order_id);

        if($order_info === false) {
            return $this->error(OrderLogic::getErrorMessage());
        }

        $finish = in_array($order_info['state'], [OrderEnum::ORDER_DONE, OrderEnum::ORDER_REVOKED, OrderEnum::ORDER_EXPIRED]);

        return $this->success(['finish'=>$finish]);
    }

    /**
     * @notes 获取订单及商品详情
     * @param OrderRequest $request
     * @return \Dingo\Api\Http\Response
     * @author Evil丿
     * @date 2024/07/30 10:25
     */
    public function getOrderDetail(OrderRequest $request)
    {
        $order_id = $request -> get('orderId');

        $order_info = OrderLogic::getOrderDetail($order_id);

        if($order_info === false) {
            return $this->error(OrderLogic::getErrorMessage());
        }

        return $this->success($order_info);
    }

    /**
     * @notes 获取订单列表
     * @param OrderRequest $request
     * @return \Dingo\Api\Http\Response
     * @author Evil丿
     * @date 2024/07/30 11:11
     */
    public function getOrderList(OrderRequest $request)
    {
        $data = $request->all();

        $user_id = $this->user_info['id'];

        $order_list = OrderLogic::getOrderList($user_id, $data);

        if($order_list === false) {
            return $this->error(OrderLogic::getErrorMessage());
        }

        return $this->success($order_list);
    }

    /**
     * @notes 提交退款申请
     * @param OrderRequest $request
     * @return \Dingo\Api\Http\Response
     * @author Evil丿
     * @date 2024/07/30 14:56
     */
    public function setRefundOrder(OrderRequest $request)
    {
        $data = $request -> all();

        $user_id = $this -> user_info['id'];

        $res = OrderLogic::setRefundOrder($data['orderId'], $user_id, $data['refundAmount'], $data['notes']);

        if($res === false) {
            return $this->error(OrderLogic::getErrorMessage());
        }

        return $this->success($res);
    }

    /**
     * @notes 获取退款订单详情
     * @param OrderRequest $request
     * @return \Dingo\Api\Http\Response
     * @author Evil丿
     * @date 2024/07/31 14:14
     */
    public function getRefundOrderDetail(OrderRequest $request)
    {
        $order_id = $request -> get('orderId');

        $user_id = $this -> user_info['id'];

        $res = OrderLogic::getRefundOrderDetail($order_id, $user_id);

        if($res === false) {
            return $this->error(OrderLogic::getErrorMessage());
        }

        return $this->success($res);
    }

    /**
     * @notes 支付需二次支付订单
     * @param OrderRequest $request
     * @return \Dingo\Api\Http\Response
     * @author Evil丿
     * @date 2024/08/06 12:54
     */
    public function payNeedFurtherOrder(OrderRequest $request)
    {
        $order_id = $request -> get('orderId');

        $platform = $request -> get('platform');

        $res = OrderLogic::payAmountErrorOrder($order_id, $platform);

        if($res === false) {
            return $this->error(OrderLogic::getErrorMessage());
        }

        return $this->success($res);
    }
}

